package org.zn.mvcbase.session;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.zn.commons.collection.Maps;
import org.zn.commons.reflection.ObjectInvoker;

public class SynSessions {

	private HttpSession session;

	private static final Map<String, Class> excludeMap;

	static {
		excludeMap = Maps.newMap();

		excludeMap.put(String.class.getName(), String.class);
		excludeMap.put(Integer.class.getName(), Integer.class);
		excludeMap.put(int.class.getName(), int.class);
		excludeMap.put(Date.class.getName(), Date.class);
		excludeMap.put(Double.class.getName(), Double.class);
		excludeMap.put(double.class.getName(), double.class);
		excludeMap.put(Long.class.getName(), Long.class);
		excludeMap.put(long.class.getName(), Long.class);
		excludeMap.put(BigDecimal.class.getName(), BigDecimal.class);
		excludeMap.put(boolean.class.getName(), boolean.class);
		excludeMap.put(Boolean.class.getName(), Boolean.class);
		excludeMap.put(float.class.getName(), float.class);
		excludeMap.put(Float.class.getName(), Float.class);


	}

	private SynSessions() {
		// TODO Auto-generated constructor stub
	}

	public static SynSessions getSynSessions(HttpSession session) {

		SynSessions ss = new SynSessions();

		ss.session = session;
		return ss;

	}

	/**
	 * 
	 * @param region
	 * @param key  toUpper   
	 * @param value  entity  field.name toUpper
	 * 
	 * mapkey = key '.' entity field.name  ex
	 * example   ('AUTH','user', {'name':'AA','psw':'123'})     map:  {'USER.NAME':'AA','USER.PSW':'123'}
	 */
	@SuppressWarnings("unchecked")
	public void putSynSession(String region, String key, Object value) {

		Map<String, Object> regionMap  = (Map<String, Object>) session.getAttribute(region);
		if (regionMap == null) {
		
			regionMap = Maps.newMap();
			
		}

		Class clazz = value.getClass();

		if (excludeMap.get(clazz.getName()) != null) {

			regionMap.put(key.toUpperCase(), value);

		} else {

			ObjectInvoker oi = ObjectInvoker.wrapper(value);
			Field fieds[] = clazz.getDeclaredFields();

			for (Field field : fieds) {
				
				SessionIgnore si=field.getAnnotation(SessionIgnore.class);	

				if(si!=null) continue; 
				
				String fk = field.getName();

				try {

					Object ov = oi.InvokeMethod(oi.getterName(fk), null);

					if(ov==null) continue;
					
					regionMap.put(key.toUpperCase() + "." + fk.toUpperCase(), ov);

				} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
						| InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}

		}
		
		
		session.setAttribute(region, regionMap);

	}

	public Map<String, Object> getSynSessionRegionMap(String region) {

		Map<String, Object> regionMap = (Map<String, Object>) session.getAttribute(region);
		return regionMap;
	}
	
	public Object getSynSessionRegionValue(String region,String key) {

		Map<String, Object> regionMap = (Map<String, Object>) session.getAttribute(region);
		return regionMap.get(key.toUpperCase());
	}
	

}
